﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

using ZetaPrints.ZetaClient.Business.ThreadSubSytem;
using ZetaPrints.ZetaClient.Data;
using ZetaPrints.ZetaClient.Data.Repository;
using ZetaPrints.ZetaClient.Data.Repository.Linq;
using ZetaPrints.ZetaClient.Shared;

namespace ZetaPrints.ZetaClient.Business
{
    /// <summary>
    /// This should be the base of all the managers,
    /// since this takes in the minimum for database access
    /// and we access
    /// </summary>
    public abstract class BaseManager
    {
        #region protected attributes
        /// <summary>
        /// This is the are to access the database
        /// </summary>
        protected DataRepositoryManager _dataRepositoryManager;
        /// <summary>
        /// This is the control to access data on the site
        /// </summary>
        protected WebAction _webAction;
        #endregion


        #region events
        /// <summary>
        /// This is the event that happens when a message needs to get to the 
        /// presentation. Also actions will be done from this. When a thread
        /// finishes something it will send messages to the presentation layer
        /// for a refresh.
        /// </summary>
        public event EventHandler<EventMessenger> OnEventMessenger;
        #endregion


        #region public properties
        /// <summary>
        /// The thread system to control it all.
        /// </summary>
        public ThreadManager ThreadManager{get;set;}
        /// <summary>
        /// This is so we can pass to the children when it comes
        /// the time
        /// </summary>
        public Site SiteEntry { get; set; }
        /// <summary>
        /// If the thread within are alive
        /// </summary>
        /// <returns></returns>
        public abstract bool AreThreadsAlive { get; }
        #endregion


        #region constructors
        /// <summary>
        /// Initlize the base access system.
        /// </summary>
        public BaseManager()
        {
            Initialize(null);
        }
        /// <summary>
        /// Initialze and already put the web action to work
        /// </summary>
        /// <param name="site"></param>
        public BaseManager(Site site)
        {
            Initialize(site);
        }
        /// <summary>
        /// Creates the site object from only the name
        /// </summary>
        /// <param name="siteName"></param>
        public BaseManager(string siteName)
        {
            /// get the name using the site manager system.
            SiteManager siteManager = new SiteManager(siteName);
            Initialize(siteManager.SiteEntry);
        }
        #endregion


        #region event handler
        /// <summary>
        /// Gets the messages from the WebAction and send it up 
        /// to the listener
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void base_OnEventMessenger(object sender, EventMessenger e)
        {
            /// if there is someone listening send it.
            if (OnEventMessenger != null)
            {
                OnEventMessenger(sender, e);
            }
        }
        #endregion


        #region private methods
        private void Initialize(Site site)
        {
            SiteEntry = site;
            _dataRepositoryManager = new DataRepositoryManager();
            ThreadManager = new ThreadManager();

            if (site == null)
            {
                _webAction = null;
            }
            else
            {
                _webAction = new WebAction(site.SiteName, site.ApiKey);
            }
        }
        #endregion


        #region protected methods
        #region message system
        /// <summary>
        /// Easier method to send messages to the presentation layer
        /// </summary>
        /// <param name="body"></param>
        protected void SendMessage(MessageTypeOption messageType, string message)
        {
            base_OnEventMessenger(this, new EventMessenger(messageType, message));
        }
        /// <summary>
        /// Easier method to send messages to the presentation layer
        /// </summary>
        /// <param name="body"></param>
        protected void SendMessage(MessageTypeOption messageType, object messageObject)
        {
            base_OnEventMessenger(this, new EventMessenger(messageType, messageObject));
        }
        #endregion
        #endregion


        #region public methods
        #region xml
        /// <summary>
        /// Returns an xml for this entry
        /// </summary>
        /// <returns></returns>
        public virtual XElement ToXml()
        {
            return new XElement("Empty");

        }
        /// <summary>
        /// We do nothing here.
        /// </summary>
        /// <param name="xElement"></param>
        public virtual void ParseXml(XElement xElement)
        {
        }
        #endregion
        #region thread
        /// <summary>
        /// This will make whatever stop everything that is been done.
        /// </summary>
        public virtual void AbortAllThreads()
        {
            /// stop everthing
            ThreadManager.AbortAllThreads();
        }
        #endregion
        #endregion
    }
}
